package BaseService

import (
	"database/sql"
	"github.com/gogf/gf/v2/crypto/gmd5"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"seawolf-admin-go/internal/request/BaseReq"
	"seawolf-admin-go/utility/MyCfg"
	"seawolf-admin-go/utility/db"
	"seawolf-admin-go/utility/response"
	"seawolf-admin-go/utility/tools"
	"strings"
	"time"
)

func Page(r *ghttp.Request, req *BaseReq.I) *response.JsonResponse {
	if req.PageSize == 0 {
		req.PageSize = 20
	}
	if req.Page == 0 {
		req.Page = 1
	}
	ctx := r.GetCtx()
	condition := g.Map{}
	obj := db.GetUnSafaTable(ctx, req.TableName)
	countObj := db.GetUnSafaTable(ctx, req.TableName)
	// 默认全部表别名先设置为 a
	asName := "a"
	// 处理查询的列
	selectFields := ""
	defaultSelectFields := strings.Split(obj.GetFieldsStr(), ",")

	pageQueryOp := req.PageQueryOp
	if pageQueryOp != nil {
		if pageQueryOp.AsName != "" {
			asName = pageQueryOp.AsName
		}
	}
	// 有设置表别名
	obj.As(asName)
	countObj.As(asName)
	// 获取查询条件
	GetCondition(r, condition, pageQueryOp, asName)
	obj.Where(
		condition,
	)
	countObj.Where(
		condition,
	)

	if pageQueryOp != nil {
		if len(pageQueryOp.SelectFields) > 0 {
			// 设置了 select 的
			selectFields = strings.Join(pageQueryOp.SelectFields, ",")
		}
		if pageQueryOp.OrderBy != "" {
			obj.Order(pageQueryOp.OrderBy)
		}
	}
	// 设置 select
	if selectFields != "" {
		obj.Fields(selectFields)
	} else {
		for k, v := range defaultSelectFields {
			defaultSelectFields[k] = asName + "." + v
		}
		obj.Fields(strings.Join(defaultSelectFields, ","))
	}
	// 处理查询里 --- end ---
	if pageQueryOp != nil {
		// 缓存
		if pageQueryOp.IsCache > 0 && MyCfg.GetSiteConfig[bool](ctx, "BaseCacheIsOpen") {
			countObj.Cache(gdb.CacheOption{
				Name: "backCache:" + req.TableName + ":pageCount:" + gmd5.MustEncrypt(condition),
				// 缓存时间
				Duration: time.Duration(pageQueryOp.IsCache) * time.Second,
			})
			obj.Cache(gdb.CacheOption{
				Name: "backCache:" + req.TableName + ":list:" + gmd5.MustEncrypt(condition),
				// 缓存时间
				Duration: time.Duration(pageQueryOp.IsCache) * time.Second,
			})
		}
		for _, item := range pageQueryOp.LeftJoin {
			obj.LeftJoin(item.TableInfo, item.Condition)
			countObj.LeftJoin(item.TableInfo, item.Condition)
		}
	}
	if req.SoftDeleteField != "" {
		countObj.Where(asName+"."+req.SoftDeleteField, 0)
		obj.Where(asName+"."+req.SoftDeleteField, 0)
	}
	count, countErr := countObj.Fields("1").Count()
	if countErr != nil {
		return response.FailByRequestMessage(nil, countErr.Error())
	}
	res, err := obj.Page(req.Page, req.PageSize).All()
	if err != nil {
		if err != sql.ErrNoRows {
			// 非 结果为空
			return response.FailByRequestMessage(nil, err.Error())
		}
	}
	resList := res.List()
	if req.PageAfterFn != nil {
		// 处理数据
		resList, err = req.PageAfterFn(r, resList)
		if err != nil {
			return response.FailByRequestMessage(nil, err.Error())
		}
	}
	return response.SuccessByRequestMessageData(nil, "获取成功",
		g.Map{
			"list":       resList,
			"pagination": tools.GetPageInfo(count, req.Page, req.PageSize),
		})
}
